package com.juyu.reader.pc.common;

import java.io.IOException;
import java.io.Writer;
import java.util.Enumeration;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateNumberModel;
import freemarker.template.TemplateScalarModel;

public class PageDirective implements TemplateDirectiveModel {

	private HttpServletRequest request;
	private int pageSize = 15; // 每页要显示的记录数

	public PageDirective(HttpServletRequest request, int pageSize) {
		this.request = request;
		if (pageSize > 0) {
			this.pageSize = pageSize;
		}
	}

	@Override
	public void execute(Environment env, Map params, TemplateModel[] arg2, TemplateDirectiveBody body)
			throws TemplateException, IOException {
		Writer out = env.getOut();

		String url = ""; // 请求URI

		int pageNo = 1; // 当前页号
		int recordCount; // 总记录数

		// 将模版里的数字参数转化成int类型的方法，其它类型的转换请看freemarker文档
		// TemplateModel paramValue = (TemplateModel) params.get("num");
		// recordCount = ((TemplateNumberModel)
		// paramValue).getAsNumber().intValue();
		url = ((TemplateScalarModel) params.get("url")).getAsString();
		try {
			pageNo = ((TemplateNumberModel) params.get("pageNo")).getAsNumber().intValue();
		} catch (Exception e) {
		}
		recordCount = ((TemplateNumberModel) params.get("recordCount")).getAsNumber().intValue();

		int pageCount = (recordCount + pageSize - 1) / pageSize; // 计算总页数

		// 拼写要输出到页面的HTML文本
		StringBuilder sb = new StringBuilder();

		sb.append("<style type=\"text/css\">");
		sb.append(".pagination {padding: 5px;float:left;font-size:14px;}");
		sb.append(
				".pagination a, .pagination a:link, .pagination a:visited {padding:2px 5px;margin:2px;border:1px solid #7fcd60;text-decoration:none;color:#7fcd60;}");
		sb.append(
				".pagination a:hover, .pagination a:active {border: 1px solid #ff0000;color: #000;text-decoration: none;}");
		sb.append(
				".pagination span.current {padding: 2px 5px;margin: 2px;border: 1px solid #7fcd60;font-weight: bold;background-color: #7fcd60;color: #FFF;}");
		sb.append(".pagination span.disabled {padding: 2px 5px;margin: 2px;border: 1px solid #eee; color: #ddd;}");
		sb.append("</style>\r\n");
		sb.append("<div class=\"pagination\">\r\n");
		if (recordCount == 0) {
			sb.append("<strong>没有可显示的项目</strong>\r\n");
		} else {
			// 页号越界处理
			if (pageNo > pageCount) {
				pageNo = pageCount;
			}
			if (pageNo < 1) {
				pageNo = 1;
			}

			sb.append("<form method=\"post\" action=\"").append(url).append("\"name=\"pageForm\">\r\n");

			// 获取请求中的所有参数
			// HttpServletRequest request = (HttpServletRequest)
			// pageContext.getRequest();
			Enumeration<String> enumeration = request.getParameterNames();
			String name = null; // 参数名
			String value = null; // 参数值
			// 把请求中的所有参数当作隐藏表单域
			while (enumeration.hasMoreElements()) {
				name = enumeration.nextElement();
				value = request.getParameter(name);
				// 去除页号
				if (name.equals("pageNo")) {
					if (null != value && !"".equals(value)) {
						pageNo = Integer.parseInt(value);
					}
					continue;
				}
				sb.append("<input type=\"hidden\" name=\"").append(name).append("\" value=\"").append(value)
						.append("\"/>\r\n");
			}

			// 把当前页号设置成请求参数
			sb.append("<input type=\"hidden\" name=\"").append("pageNo").append("\" value=\"").append(pageNo)
					.append("\"/>\r\n");

			// 输出统计数据
			sb.append("&nbsp;共<strong>").append(recordCount).append("</strong>条记录").append(",<strong>")
					.append(pageCount).append("</strong>页:&nbsp;\r\n");

			// 上一页处理
			if (pageNo == 1) {
				sb.append("<span class=\"disabled\">&laquo;&nbsp;上一页").append("</span>\r\n");
			} else {
				sb.append("<a href=\"javascript:turnOverPage(").append((pageNo - 1))
						.append(")\">&laquo;&nbsp;上一页</a>\r\n");
			}

			// 如果前面页数过多,显示"..."
			int start = 1;
			if (pageNo > 4) {
				start = pageNo - 2;//前显示2
				sb.append("<a href=\"javascript:turnOverPage(1)\">1</a>\r\n");
				sb.append("<a href=\"javascript:turnOverPage(2)\">2</a>\r\n");
				sb.append("&hellip;\r\n");
			}
			// 显示当前页附近的页
			int end = pageNo + 2;//后显示2
			if (end > pageCount) {
				end = pageCount;
			}
			for (int i = start; i <= end; i++) {
				if (pageNo == i) { // 当前页号不需要超链接
					sb.append("<span class=\"current\">").append(i).append("</span>\r\n");
				} else {
					sb.append("<a href=\"javascript:turnOverPage(").append(i).append(")\">").append(i)
							.append("</a>\r\n");
				}
			}
			// 如果后面页数过多,显示"..."
			if (end < pageCount - 3) {
				sb.append("&hellip;\r\n");
			}
			if (end < pageCount - 2) {
				sb.append("<a href=\"javascript:turnOverPage(").append(pageCount - 2).append(")\">")
						.append(pageCount - 2).append("</a>\r\n");
			}
			if (end < pageCount - 1) {
				sb.append("<a href=\"javascript:turnOverPage(").append(pageCount - 1).append(")\">")
						.append(pageCount - 1).append("</a>\r\n");
			}
			if (end < pageCount) {
				sb.append("<a href=\"javascript:turnOverPage(").append(pageCount).append(")\">").append(pageCount)
						.append("</a>\r\n");
			}

			// 下一页处理
			if (pageNo == pageCount) {
				sb.append("<span class=\"disabled\">下一页&nbsp;&raquo;").append("</span>\r\n");
			} else {
				sb.append("<a href=\"javascript:turnOverPage(").append((pageNo + 1))
						.append(")\">下一页&nbsp;&raquo;</a>\r\n");
			}
			sb.append("</form>\r\n");

			// 生成提交表单的JS
			sb.append("<script language=\"javascript\">\r\n");
			sb.append("  function turnOverPage(no){\r\n");
			sb.append("    if(no>").append(pageCount).append("){");
			sb.append("      no=").append(pageCount).append(";}\r\n");
			sb.append("    if(no<1){no=1;}\r\n");
			sb.append("    document.pageForm.pageNo.value=no;\r\n");
			sb.append("    document.pageForm.submit();\r\n");
			sb.append("  }\r\n");
			sb.append("</script>\r\n");
		}
		sb.append("</div>\r\n");
		out.write(sb.toString());
		// out.write("Akishimo num=" + params.get("num") + "的类型为:" +
		// paramValue.getClass());
		if (body != null) {
			body.render(env.getOut());
		} else {
			throw new RuntimeException("body is null");
		}

	}

}
